﻿using System.Data;
using System.Reflection;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text.RegularExpressions;
using 表格处理类 = MiniExcelLibs;

namespace 战斗系统原型
{
    internal class 辅助类
    {
        /// <summary>
        /// 返回正则符合正则表达式，并且匹配后的子文本项
        /// </summary>
        /// <param name="一段文本">原文本</param>
        /// <param name="正则表达式">正则表达式</param>
        /// <param name="匹配">匹配索引</param>
        /// <param name="子匹配">子匹配索引</param>
        /// <returns>返回0为匹配空</returns>
        public string 正则子匹配文本(string 一段文本, string 正则表达式, int 匹配, int 子匹配)

        {

            Regex 匹配器 = new Regex(正则表达式);
            var 匹配集 = 匹配器.Matches(一段文本);
            if (匹配集.Count == 0)
            { return "Error"; }
            return 匹配集[匹配].Groups[子匹配 + 1].Value;

        }


        public static T 拷贝类<T>(T 实体类)
        {
            using (Stream objectStream = new MemoryStream())
            {
                //利用 System.Runtime.Serialization序列化与反序列化完成引用对象的复制
                IFormatter formatter = new BinaryFormatter();
                formatter.Serialize(objectStream, 实体类);
                objectStream.Seek(0, SeekOrigin.Begin);
                return (T)formatter.Deserialize(objectStream);
            }
        }
        public static T 拷贝类_反射<T>(T obj)
        {
            if (obj is string || obj.GetType().IsValueType)
                return obj;

            object retval = Activator.CreateInstance(obj.GetType());
            FieldInfo[] fields = obj.GetType().GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance);
            foreach (var field in fields)
            {
                try
                {
                    field.SetValue(retval, 拷贝类(field.GetValue(obj)));
                }
                catch { }
            }

            return (T)retval;
        }

    }

    internal class MiniExcel辅助类
    {
        #region 结构体
        public string 文件路径 { get; set; }
        public string 表名称 { get; set; }
        public object 结构体类 { get; set; }
        #endregion
        #region 初始化类
        /// <summary>
        /// 初始化MiniExcel辅助类 指定完整内容，可使用所有功能。
        /// </summary>
        /// <param name="路径">Excel文件所存放的路径</param>
        /// <param name="结构体">Excel文件所对应的强类型结构体</param>
        /// <param name="表名">需要载载入的表名</param>
        public MiniExcel辅助类(string 路径, object 结构体, string 表名 = "未定义")
        {
            文件路径 = 路径;
            结构体类 = 结构体;
            表名称 = 表名;
        }

        /// <summary>
        /// 初始化MiniExcel辅助类 仅指定路径和表名，使用有限的功能
        /// </summary>
        /// <param name="路径">Excel文件所存放的路径</param>
        /// <param name="表名">需要载载入的表名</param>
#pragma warning disable CS8618 // 在退出构造函数时，不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
        public MiniExcel辅助类(string 路径, string 表名 = "未定义")
#pragma warning restore CS8618 // 在退出构造函数时，不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。
        {
            文件路径 = 路径;
            表名称 = 表名;
        }
        #endregion
        #region 读写文件
        /// <summary>
        ///  读取一个文件到DataTable
        /// </summary>
        /// <param name="表名">表格名称</param>
        /// <param name="第一行是否为表头">第一行是否是表头</param>
        /// <returns></returns>
#pragma warning disable CS8625 // 无法将 null 字面量转换为非 null 的引用类型。
        public DataTable 从Excel转DataTable(string 表名 = null, bool 第一行是否为表头 = false)
#pragma warning restore CS8625 // 无法将 null 字面量转换为非 null 的引用类型。
        {
#pragma warning disable CS0618 // 类型或成员已过时
            return 表格处理类.MiniExcel.QueryAsDataTable(文件路径, 第一行是否为表头, 表名);
#pragma warning restore CS0618 // 类型或成员已过时

        }

        /// <summary>
        ///  将一个DataTable表格储存到Excel文档中
        /// </summary>
        /// <param name="表格">DataTable类型的表格</param>
        /// <param name="文件路径">需要储存到的文件路径</param>
        /// <param name="是否同步">该存储过程是否同步，是则为同步，否则为异步执行</param>
        public void 储存文档(DataTable 表格, string 文件路径, bool 是否同步 = false)
        {
            if (是否同步)
            { 表格处理类.MiniExcel.SaveAsAsync(文件路径, 表格); }
            else
            { 表格处理类.MiniExcel.SaveAs(文件路径, 表格); }
        }
        /// <summary>
        ///  将一个DataSet表格集储存到Excel文档中
        /// </summary>
        /// <param name="表格">DataSet类型的表格集</param>
        /// <param name="文件路径">需要储存到的文件路径</param>
        /// <param name="是否同步">该存储过程是否同步，是则为同步，否则为异步执行</param>
        public void 储存文档(DataSet 表格, string 文件路径, bool 是否同步 = false)
        {
            if (是否同步)
            { 表格处理类.MiniExcel.SaveAs(文件路径, 表格); }
            else
            { 表格处理类.MiniExcel.SaveAsAsync(文件路径, 表格); }
        }

        /// <summary>
        /// 套用已经做好的Excel模板，并填入数据保存
        /// 若提示实例未引用，请检查Excel模板中是否有错误的“{{a.b}}”一般是b出现了错误。
        /// </summary>
        /// <param name="模板位置">Excel模板的路径</param>
        /// <param name="保存位置">套用模板后的输出路径</param>
        /// <param name="数据表">要填入的数据表，请注意要填写好数据表的列名</param>
        /// <param name="数据表前缀">要填入的数据表前缀，需要在该列中提前将其设置为“{{数据表前缀.列名}}”</param>
        /// <param name="替换字典">需要替换的字典，若无其他需要替换的数据，则可传入一个空字典</param>
        /// <param name="是否同步执行">储存过程是否同步，是则为同步，否则为异步执行</param>
        public void 套用模板并储存(string 模板位置, string 保存位置, DataTable 数据表, string 数据表前缀, Dictionary<string, object> 替换字典, bool 是否同步执行)
        {

            替换字典.Add(数据表前缀, 数据表);
            if (是否同步执行) { 表格处理类.MiniExcel.SaveAsByTemplateAsync(保存位置, 模板位置, 替换字典); }
            else
            { 表格处理类.MiniExcel.SaveAsByTemplate(保存位置, 模板位置, 替换字典); }

        }
        #endregion
    }
}
